import os
import argparse
import uuid

filters = list()
files = list()


def get_vc_header():
    header = """<?xml version="1.0" encoding="utf-8"?>
  <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|ARM">
      <Configuration>Debug</Configuration>
      <Platform>ARM</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|ARM">
      <Configuration>Release</Configuration>
      <Platform>ARM</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|x86">
      <Configuration>Debug</Configuration>
      <Platform>x86</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|x86">
      <Configuration>Release</Configuration>
      <Platform>x86</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|x64">
      <Configuration>Release</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <ProjectGuid>{d14472f1-e80c-4d22-a2b5-6694cdc04c48}</ProjectGuid>
    <Keyword>Linux</Keyword>
    <RootNamespace>makefile</RootNamespace>
    <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
    <ApplicationType>Linux</ApplicationType>
    <ApplicationTypeRevision>1.0</ApplicationTypeRevision>
    <TargetLinuxPlatform>Generic</TargetLinuxPlatform>
    <LinuxProjectType>{FC1A4D80-50E9-41DA-9192-61C0DBAA00D2}</LinuxProjectType>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
    <UseDebugLibraries>true</UseDebugLibraries>
    <ConfigurationType>Makefile</ConfigurationType>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
    <UseDebugLibraries>false</UseDebugLibraries>
    <ConfigurationType>Makefile</ConfigurationType>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'" Label="Configuration">
    <UseDebugLibraries>true</UseDebugLibraries>
    <ConfigurationType>Makefile</ConfigurationType>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" Label="Configuration">
    <UseDebugLibraries>false</UseDebugLibraries>
    <ConfigurationType>Makefile</ConfigurationType>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <UseDebugLibraries>true</UseDebugLibraries>
    <ConfigurationType>Makefile</ConfigurationType>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
    <UseDebugLibraries>false</UseDebugLibraries>
    <ConfigurationType>Makefile</ConfigurationType>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings" />
  <ImportGroup Label="Shared" />
  <ImportGroup Label="PropertySheets" />
  <PropertyGroup Label="UserMacros" />
    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
    <LocalRemoteCopySources>false</LocalRemoteCopySources>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <LocalRemoteCopySources>false</LocalRemoteCopySources>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
    <LocalRemoteCopySources>false</LocalRemoteCopySources>
  </PropertyGroup>
    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
    <LocalRemoteCopySources>false</LocalRemoteCopySources>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <LocalRemoteCopySources>false</LocalRemoteCopySources>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
    <LocalRemoteCopySources>false</LocalRemoteCopySources>
  </PropertyGroup>
  """
    return header


def get_vc_footer():
    footer = """
    <ItemDefinitionGroup />
    <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
    <ImportGroup Label="ExtensionTargets" />
    </Project>
    """
    return footer


def get_vc_others(path):
    val = os.popen(
        r'cd ' + str(path) + r';find . -not -path "*/\.*" -type f ! '
                             r'-iname "*.c" ! -iname "*.cpp" ! -iname "*.h" ! -iname "*.txt" ! '
                             r'-iname "*.o" ! -iname "*.vcxproj" ! -iname "*.filters"')
    ret = list()
    for i in list(val.readlines()):
        file_name = i.replace("\n", "").replace('/', '\\')
        ret.append("\"".join(["    <None Include=", file_name, " />\n"]))
    ret = ''.join(ret)
    return "\n".join(["  <ItemGroup>", ret, "  </ItemGroup>"])


def get_vc_text(path):
    val = os.popen(
        r'cd ' + str(path) + r';find . -not -path "*/\.*" -type f -iname "*.txt"'
    )
    ret = list()
    for i in val.readlines():
        file_name = i.replace("\n", "").replace('/', '\\')
        ret.append("\"".join(["    <Text Include=", file_name, " />\n"]))
    ret = ''.join(ret)
    return "\n".join(["  <ItemGroup>", ret, "  </ItemGroup>"])


def get_vc_compile(path):
    val = os.popen(
        r'cd ' + str(path) + r';find . -not -path "*/\.*" -type f -iname "*.c" -or -iname "*.cpp"'
    )
    ret = list()
    for i in val.readlines():
        file_name = i.replace("\n", "").replace('/', '\\')
        ret.append("\"".join(["    <ClCompile Include=", file_name, " />\n"]))
    ret = ''.join(ret)
    return "\n".join(["  <ItemGroup>", ret, "  </ItemGroup>"])


def get_vc_include(path):
    val = os.popen(
        r'cd ' + str(path) + r';find . -not -path "*/\.*" -type f -iname "*.h"'
    )
    ret = list()
    for i in val.readlines():
        file_name = i.replace("\n", "").replace('/', '\\')
        ret.append("\"".join(["    <ClInclude Include=", file_name, " />\n"]))
    ret = ''.join(ret)
    return "\n".join(["  <ItemGroup>", ret, "  </ItemGroup>"])


def get_filter_header():
    ret = """<?xml version=\"1.0\" encoding=\"utf-8\"?>
<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">
    """
    return ret


def get_filter_footer():
    return r"</Project>"


def get_filters(path):
    val = os.popen(
        r'cd ' + str(path) + r';find . -not -path "*/\.*" -type d'
    )

    ret = list()
    for i in val.readlines():
        file_name = i.replace("\n", "").replace('/', '\\')
        uuids = str(uuid.uuid4())
        ret.append("\"".join(["    <Filter Include=", file_name, ">\n"]))
        ret.append("".join(["      <UniqueIdentifier>{", uuids, "}</UniqueIdentifier>\n"]))
        ret.append("    </Filter>\n")
    ret = ''.join(ret)
    return "\n".join(["  <ItemGroup>", ret, "  </ItemGroup>"])


def get_filter_others(path):
    val = os.popen(
        r'cd ' + str(
            path) + r';find . -not -path " * /\.*" -type f ! -iname "*.c" ! -iname "*.cpp" ! '
                    r'-iname "*.h" ! -iname "*.txt" ! -iname "*.o" ! -iname "*.vcxproj"'
    )
    ret = list()

    # i="./roms/edk2/CryptoPkg/Library/OpensslLib/openssl/fuzz/corpora/x509/1dbb6bd1c49e2ff27c71645a62964abdd31a947b"
    # d=${i%/*} ./roms/edk2/CryptoPkg/Library/OpensslLib/openssl/fuzz/corpora/x509
    # fd=${d##*/} 当前目录 x509

    # fp=${d##./} roms/edk2/CryptoPkg/Library/OpensslLib/openssl/fuzz/corpora/x509
    # fp=${fp//\//\\}  roms\edk2\CryptoPkg\Library\OpensslLib\openssl\fuzz\corpora\x509

    # d=${d//\//\\} 换过斜杠的目录 .\roms\edk2\CryptoPkg\Library\OpensslLib\openssl\fuzz\corpora\x509
    # f=${i##*/} 最后文件名 1dbb6bd1c49e2ff27c71645a62964abdd31a947b
    for i in val.readlines():
        d = '\\'.join(i.replace("\n", "").replace('/', '\\').split('\\')[:-1])
        fd = i.replace("\n", "").split('/')[-2]
        fp = '\\'.join(i.replace("\n", "").replace('/', '\\').split('\\')[1:-1])
        f = i.replace("\n", "").split('/')[-1]
        if fd == ".":
            ret.append("\"".join(["    <None Include=", d + "\\" + f, " />\n"]))
        else:
            ret.append("\"".join(["    <None Include=", d + "\\" + f, ">\n"]))
            ret.append("\"".join(["      <Filter>", fp, "</Filter>\n"]))
            ret.append('    </None>\n')
    ret = ''.join(ret)
    return "\n".join(["  <ItemGroup>", ret, "  </ItemGroup>"])


def get_filter_txt(path):
    val = os.popen(
        r'cd ' + str(
            path) + r';find . -not -path "*/\.*" -type f -iname "*.txt"'
    )
    ret = list()
    for i in val.readlines():
        d = '\\'.join(i.replace("\n", "").replace('/', '\\').split('\\')[:-1])
        fd = i.replace("\n", "").split('/')[-2]
        fp = '\\'.join(i.replace("\n", "").replace('/', '\\').split('\\')[1:-1])
        f = i.replace("\n", "").split('/')[-1]
        if fd == ".":
            ret.append("\"".join(["    <Text Include=", d + "\\" + f, " />\n"]))
        else:
            ret.append("\"".join(["    <Text Include=", d + "\\" + f, ">\n"]))
            ret.append("\"".join(["      <Filter>", fp, "</Filter>\n"]))
            ret.append('    </Text>\n')
    ret = ''.join(ret)
    return "\n".join(["  <ItemGroup>", ret, "  </ItemGroup>"])


def get_filter_compile(path):
    val = os.popen(
        r'cd ' + str(
            path) + r';find . -not -path "*/\.*" -type f -iname "*.c" -or -iname "*.cpp"'
    )
    ret = list()
    for i in val.readlines():
        d = '\\'.join(i.replace("\n", "").replace('/', '\\').split('\\')[:-1])
        fd = i.replace("\n", "").split('/')[-2]
        fp = '\\'.join(i.replace("\n", "").replace('/', '\\').split('\\')[1:-1])
        f = i.replace("\n", "").split('/')[-1]
        if fd == ".":
            ret.append("\"".join(["    <ClCompile Include=", d + "\\" + f, " />\n"]))
        else:
            ret.append("\"".join(["    <ClCompile Include=", d + "\\" + f, ">\n"]))
            ret.append("\"".join(["      <Filter>", fp, "</Filter>\n"]))
            ret.append('    </ClCompile>\n')
    ret = ''.join(ret)
    return "\n".join(["  <ItemGroup>", ret, "  </ItemGroup>"])


def get_filter_include(path):
    val = os.popen(
        r'cd ' + str(path) + r';find . -not -path "*/\.*" -type f -iname "*.h"'
    )
    ret = list()
    for i in val.readlines():
        d = '\\'.join(i.replace("\n", "").replace('/', '\\').split('\\')[:-1])
        fd = i.replace("\n", "").split('/')[-2]
        fp = '\\'.join(i.replace("\n", "").replace('/', '\\').split('\\')[1:-1])
        f = i.replace("\n", "").split('/')[-1]
        if fd == ".":
            ret.append("\"".join(["    <ClInclude Include=", d + "\\" + f, " />\n"]))
        else:
            ret.append("\"".join(["    <ClInclude Include=", d + "\\" + f, " >\n"]))
            ret.append("\"".join(["      <Filter>", fp, "</Filter>\n"]))
            ret.append('    </ClInclude>\n')
    ret = ''.join(ret)
    return "\n".join(["  <ItemGroup>", ret, "  </ItemGroup>"])


def main():
    parser = argparse.ArgumentParser(description='这个工程可以把现有linux的C++工程,'
                                                 '搜索导入到vs2019的工程里面里面')
    parser.add_argument('path', type=str, help='指定要转换工程的目录')
    parser.add_argument('name', type=str, help='指定要转换的工程名')
    parser.parse_args()
    args = parser.parse_args()
    print(args.name, args.path)
    project_path, project_name = args.path.split("=")[1], args.name.split("=")[1]

    if not os.path.exists(project_path):
        print('指定文件或者目录不存在')
        exit(-1)
    if not os.listdir(project_path):
        print("指定文件夹为空")
        exit(-1)
    # get_file(project_path)

    ret_vcxproj = "\n".join([
        get_vc_header(),
        get_vc_others(project_path),
        get_vc_text(project_path),
        get_vc_compile(project_path),
        get_vc_include(project_path),
        get_vc_footer()])

    ret_filters = "\n".join([
        get_filter_header(),
        get_filters(project_path),
        get_filter_others(project_path),
        get_filter_txt(project_path),
        get_filter_compile(project_path),
        get_filter_include(project_path),
        get_filter_footer(),
    ])

    fd1 = open(str(project_path) + "/" + str(project_name) + '.vcxproj', 'w')
    fd1.write(ret_vcxproj)
    fd1.close()

    fd2 = open(str(project_path) + "/" + str(project_name) + '.vcxproj.filters', 'w')
    fd2.write(ret_filters)
    fd2.close()


if __name__ == '__main__':
    main()
